using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using System.Collections.Specialized;
using System.Xml;

namespace PointBridge.SPAssist
{
    public class SPAssistant
    {
        #region Constractors
        public SPAssistant(SPWeb p_web, string p_groupName)
        {
            web = p_web;
            groupName = p_groupName;
        }
        #endregion

        #region Methods
        public void ReleaseWeb()
        {
            web.Update();
            web = null;
        }

        public bool DeleteGroupSiteColumns()
        {
            bool deleted = false;
            foreach (SPField field in web.Fields)
            {
                if (field.Group == groupName)
                {
                    field.Delete();
                    deleted = true;
                    break;
                }
            }
            web.Update();
            if (deleted == true) return DeleteGroupSiteColumns();
            else return true;
        }
        public bool DeleteGroupContentTypes()
        {
            bool deleted = false;
            foreach (SPContentType contentType in web.ContentTypes)
            {
                if (contentType.Group == groupName)
                {
                    contentType.Delete();
                    deleted = true;
                    break;
                }
            }
            web.Update();
            if (deleted == true) return DeleteGroupSiteColumns();
            else return true;
        }

        public void RenameTitle(SPList list, string newName)
        {
            SPField titleField = list.Fields["Title"];
            titleField.Title = newName;
            titleField.Update();
            web.Update();
        }
        public void DeleteSiteColumn(string fieldName)
        {
            //delete if we can find it
            try { web.Fields[fieldName].Delete(); }
            catch (ArgumentException) { }
            catch (NullReferenceException) { }
            web.Update();
        }

        public SPFieldLookup CreateLookupSiteColumn(string fieldName, Guid lookupListGuid, string lookupFieldName, Guid lookupWebGuid)
        {
            //check to make sure that content type with this name does not already exist
            VerifySiteColumnDoesNotExist(fieldName);

            //create a field and save it
            string name = web.Fields.AddLookup(fieldName, lookupListGuid, lookupWebGuid, true);
            SPFieldLookup lookup = (SPFieldLookup)web.Fields.GetField(name);
            lookup.LookupField = lookupFieldName;
            SetFieldGroupAndUpdateField(lookup);
            web.Update();

            //lookup the field and set up the lookup column
            //SPFieldLookup lookup = new SPFieldLookup(web.Fields, name);

            return lookup;
        }
        public SPFieldChoice CreateChoiceSiteColumn(string fieldName, StringCollection choices)
        {
            //check to make sure that content type with this name does not already exist
            VerifySiteColumnDoesNotExist(fieldName);

            string name = web.Fields.Add(fieldName, SPFieldType.Choice, true, false, choices);
            SPFieldChoice field = (SPFieldChoice)web.Fields.GetField(name);
            SetFieldGroupAndUpdateField(field);
            web.Update();

            return field;
        }
        public SPField CreateSiteColumn(string fieldName, SPFieldType type)
        {
            //check to make sure that content type with this name does not already exist
            VerifySiteColumnDoesNotExist(fieldName);

            string name = web.Fields.Add(fieldName, type, true);
            SPField field = web.Fields.GetField(name);
            SetFieldGroupAndUpdateField(field);
            web.Update();

            return field;
        }

        public SPContentType CreateContentType(string contentTypeName, List<SPField> columns)
        {
            //create an empty content type and add it to content type collection
            SPContentType contentType = new SPContentType(web.AvailableContentTypes["Item"], web.ContentTypes, contentTypeName);
            contentType.Group = groupName;
            web.ContentTypes.Add(contentType);

            //add columns from the list to the content type
            foreach (SPField column in columns)
            {
                SPFieldLink fieldLink = new SPFieldLink(column);
                contentType.FieldLinks.Add(fieldLink);
            }
            contentType.Update();
            web.Update();

            return contentType;
        }
        public void SetContentTypeCustomForms(SPContentType contentType, string newFormUrl, string editFormUrl, string displayFormUrl)
        {
            /*
            /*
            <FormUrls xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url">
                <Edit>_layouts/EddieBauer.SafetyConcern\EditForm.aspx</Edit>
                <New>_layouts/EddieBauer.SafetyConcern\NewForm.aspx</New>
                <Display>_layouts/EddieBauer.SafetyConcern\DisplayForm.aspx</Display>
            </FormUrls>
            * /
            XmlDocument xmlDoc = new XmlDocument();

            XmlElement formsUrlElement = xmlDoc.CreateElement("FormUrls");
            formsUrlElement.SetAttribute("xmlns", "http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/url");
            xmlDoc.AppendChild(formsUrlElement);

            XmlElement EditElement = xmlDoc.CreateElement("Edit");
            EditElement.AppendChild(xmlDoc.CreateTextNode(editFormUrl));
            formsUrlElement.AppendChild(EditElement);

            XmlElement NewElement = xmlDoc.CreateElement("New");
            NewElement.AppendChild(xmlDoc.CreateTextNode(newFormUrl));
            formsUrlElement.AppendChild(NewElement);

            XmlElement DisplayElement = xmlDoc.CreateElement("Display");
            DisplayElement.AppendChild(xmlDoc.CreateTextNode(displayFormUrl));
            formsUrlElement.AppendChild(DisplayElement);

            //contentType.XmlDocuments.Delete("http://schemas.microsoft.com/sharepoint/v3/contenttype/forms");
            contentType.XmlDocuments.Add(xmlDoc);
            contentType.Update();
            */

            //explicitly set the forms
            contentType.DisplayFormUrl = displayFormUrl;
            contentType.EditFormUrl = editFormUrl;
            contentType.NewFormUrl = newFormUrl;
            contentType.Update();

            contentType.ParentWeb.Update();
        }
        public void DeleteContentType(string contentTypeName)
        {
            //delete content type
            try { web.ContentTypes[contentTypeName].Delete(); }
            catch (ArgumentException) { }
            catch (NullReferenceException) { }
            web.Update();
        }

        public SPList CreateList(string listName, string listDescription, bool onQuickLaunch, bool enableVersioning, List<SPContentType> contentTypes, bool createDafultView)
        {
            //now let's instantiate the list and configure it
            Guid listId = web.Lists.Add(listName, listDescription, SPListTemplateType.GenericList);
            SPList list = web.Lists[listId];
            list.ContentTypesEnabled = true;
            list.EnableAttachments = false;
            list.OnQuickLaunch = onQuickLaunch;
            list.EnableVersioning = enableVersioning;
            list.Update();

            //add support for content type and save
            foreach (SPContentType contentType in contentTypes) list.ContentTypes.Add(contentType);
            list.Update();

            //remove standard Item content type, if can't find, ignore exception
            try { list.ContentTypes["Item"].Delete(); }
            catch (ArgumentException) { }

            if (createDafultView == true)
            {
                //let's add a column we just added to the list to the view
                SPView view = list.Views["All Items"];
                //view.ViewFields.Delete("LinkTitle"); //delete title that is alredy there
                foreach (SPContentType contentType in contentTypes)
                {
                    foreach (SPFieldLink column in contentType.FieldLinks)
                    {
                        if (column.Name != "ContentType" && column.Name != "Title") view.ViewFields.Add(column.Name);
                    }
                }
                view.Update();
            }
            
            web.Update();

            return list;
        }
        public void DeleteList(string listName)
        {
            //delete list
            try { web.Lists[listName].Delete(); }
            catch (ArgumentException) { }
            catch (NullReferenceException) { }
            web.Update();
        }

        public void SetFieldGroupAndUpdateField(SPField field)
        {
            field.Group = groupName;
        }

        #endregion

        #region Private Helper Methods
        private void VerifySiteColumnDoesNotExist(string fieldName)
        {
            try
            {
                SPField field = web.Fields[fieldName];
                if (field.Group == groupName) throw new Exception("Site Column '" + fieldName + "' already exists in group '" + groupName + "'");
            }
            catch (ArgumentException) { }
        }
        #endregion

        #region Properties
        public SPWeb web;
        public string groupName;
        #endregion
    }
}
